#pragma once

#include <iostream>
#include <string>
#include <unordered_map>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netinet/in.h>
using namespace std;

class User
{
public:
    User(const string &ip, const uint16_t &port)
        : _ip(ip), _port(port)
    {
    }

    ~User()
    {
    }

    uint16_t Port()
    {
        return _port;
    }

    string IP()
    {
        return _ip;
    }

private:
    string _ip;     // IP
    uint16_t _port; // Port
};

class onlineUser
{
public:
    onlineUser()
    {
    }
    ~onlineUser()
    {
    }

    // 添加在线人数  上线
    void addUsers(const string &clientIP, const uint16_t &clientPort)
    {
        string ID = clientIP + "-" + to_string(clientPort);
        _users.insert(make_pair(ID, User(clientIP, clientPort)));
    }

    // 删除在线人数  下线
    void deleteUsers(const string &clientIP, const uint16_t &clientPort)
    {
        string ID = clientIP + "-" + to_string(clientPort);
        _users.erase(ID);
    }

    // 判断是否在线
    bool is_onlineUsers(const string &clientIP, const uint16_t &clientPort)
    {
        string ID = clientIP + "-" + to_string(clientPort);
        return _users.find(ID) == _users.end() ? false : true;
    }

    // 向_users中的所有人广播消息
    void broadCast(int sockfd, const uint16_t &clientPort, const string &clientIP, string message)
    {
        for (auto &user : _users)
        {
            struct sockaddr_in peer;
            bzero(&peer, sizeof(peer));
            peer.sin_addr.s_addr = inet_addr(user.second.IP().c_str());
            peer.sin_family = AF_INET; // 协议家族
            peer.sin_port = htons(user.second.Port());

            string s = "【" + clientIP + "-" + to_string(clientPort) + "】" + "# ";
            s += message;
            sendto(sockfd, s.c_str(), s.size(), 0, (struct sockaddr *)&peer, sizeof(peer));
        }
    }

private:
    unordered_map<string, User> _users; // ID 用 ip+port标识
};